import 'dart:collection';
import 'dart:math';

import 'package:flutter_menu/app_config.dart';
import 'package:flutter_menu/biz/login/login_controller.dart';
import 'package:flutter_menu/biz/order/order_controller.dart';
import 'package:flutter_menu/biz/order/record/order_record_controller.dart';
import 'package:flutter_menu/data/menu_repository.dart';
import 'package:flutter_menu/data/obx_store.dart';
import 'package:flutter_menu/exception/api_exception.dart';
import 'package:flutter_menu/menu_page.dart';
import 'package:flutter_menu/model/menu_model.dart';
import 'package:flutter_menu/model/order_model.dart';
import 'package:flutter_menu/model/product_model.dart';
import 'package:flutter_menu/model/shope_model.dart';
import 'package:flutter_menu/objectbox.g.dart';
import 'package:flutter_menu/utils/common_utils.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';

import 'order_record_pg.dart';


class ShopCarController extends GetxController {
  static ShopCarController get to => Get.find();
  final Map<String,ShopCarItem> _shopCarItem = {};
  TableInfo? _selectTableInfo;
  final AppConfig _config = Get.find();
  final MenuRepository _repository = Get.find();


  @override
  void onInit() {
    super.onInit();
  }

  @override
  void onReady() {
    super.onReady();
  }

  void setTable(TableModel? table, int? personNum) {

    if (table == null || personNum == null) {
      _selectTableInfo = null;
    } else {
      _selectTableInfo = TableInfo(table, personNum);
      // 切换房台以后，刷新点单页面
      try{
        Get.find<OrderController>().initData();
      }catch (ig){}

    }
    update();
  }

  bool get canOrder {
    if (_selectTableInfo == null) return false;
    if (_shopCarItem.isEmpty) return false;
    for (var item in _shopCarItem.values.toList()) {
      bool inTable = item.isInTable();
      if (!inTable) return false;
    }
    return true;
  }

  List<ShopCarItem> get unSupportItem {
    var tInfo = _selectTableInfo;
    if (tInfo == null) return [];
    //寻找不在菜单中的菜品
    return _shopCarItem.values.where((e) => !e.isInTable()).toList();
  }

  Map<String, List<ShopCarItem>> get shop {
    Map<String, List<ShopCarItem>> result = {};
    for (var e in _shopCarItem.values) {
      var cName = e.groupName;
      List<ShopCarItem> list = result[cName] ?? [];
      list.add(e);
      result[cName] = list;
    }
    return result;
  }

  String? get menuId => _selectTableInfo?.cMenu?.uuid;
  String? get tableId => _selectTableInfo?.selectTable.tableUuid;

  void addProduct(ShopCarItem item) {
    // if (_shopCarItem.contains(item)) {
    //   var ele = _shopCarItem.where((e) => e == item).firstOrNull;
    //   if (ele == null) {
    //     _shopCarItem.add(item);
    //   } else {
    //     if (item.count <= 0) {
    //       _shopCarItem.remove(ele);
    //     } else {
    //       ele = item;
    //     }
    //
    //   }
    // } else {
    //   _shopCarItem.add(item);
    // }
    // update();
  }

  void removeSingleShopItem(List<ShopCarItem> items) {
    for (var e in items) {
      _shopCarItem.remove(e.id);
    }
    update();
  }

  void removeShopItem(List<ShopCarItem> items) {
    for (var e in items) {
      _shopCarItem.remove(e.id);
    }

    update();
  }

  ShopCarItem? getShopCarItemByProductId(String productUuid) {
    try {
      return  _shopCarItem.values.firstWhere((item) {
        return item.productId == productUuid;
      });
    } catch (e) {
      return null;
    }
  }

  int? getProductNumber(String productUuid) {
    var item = getShopCarItemByProductId(productUuid);
    return item?.count;
  }

  void continueOrder() {
    Get.toNamed(MenuPages.Menu_Order, parameters: {
      OrderController.orderPageStatusPara: OrderPageStatus.thumbnailPage.status
    });
  }

  void editDishes(dynamic model) {
    Get.toNamed(MenuPages.Menu_Order, parameters: {
      OrderController.orderPageStatusPara: OrderPageStatus.specOptionPage.status, OrderController.productUuidPara: "30fd4f4fc6d6465c84247faef9b442b6"
    });
  }

  void lookImg(dynamic model) {
    Get.toNamed(MenuPages.Menu_Order, parameters: {
      OrderController.orderPageStatusPara: OrderPageStatus.detailPage.status, OrderController.productUuidPara: "30fd4f4fc6d6465c84247faef9b442b6"
    });
  }

  void deleteDishes(dynamic model) {
    _shopCarItem.remove(model);
    update();
  }

  void onOrder()  async{
    var loginInfo = _config.loginModel;
    if(loginInfo == null) {
      //后登录，先去登录
      Get.toNamed(MenuPages.Menu_Login,arguments: LoginArgs( invoke: () {
        return Get.offAndToNamed(MenuPages.Menu_Setting);
      }));
      return ;
    }

    if(_config.afterLogin){
      // 后登陆，并且已经登录了

      var products = unSupportItem;
      if(products.isNotEmpty){
        Get.dialog(TableChangedHintDialog(
          products,
          submit: () {
            removeShopItem(products);
            update();
            Get.back();
            onOrderRequest();
          },
        ));
      }else{
        onOrderRequest();
      }


    }else{
      // 先登录，去登录页校验密码
      Get.toNamed(MenuPages.Menu_Login,arguments: LoginArgs( invoke: () async {
        onOrderRequest();
        Get.back();
        return  ;
      }));
      return ;
    }

  }

  void onOrderRequest() async{

    try{
      if (_selectTableInfo == null)  throw "e_msg_no_table".tr;
      if (_shopCarItem.isEmpty )  throw "e_msg_shop_empty".tr;
      SmartDialog.showLoading();
      List<OrderProductRV> data = _shopCarItem.values.map((e){
        var data =  e.inTableSKU?.toOrderDataRV();
        data?.count = e.count.toDouble();
        data?.remark = e.notice;
        return data;
      } )
      .whereType<OrderProductRV>().toList();

      var request =  OrderRq(
        productList: data,
          tableUuid: _selectTableInfo!.selectTable.tableUuid);

      var res =  await _repository.order(request);
      _shopCarItem.clear();
      update();
      Get.find<OrderRecordController>().tabController.animateTo(OrderRecordController.TAB_INDEX_ORDER_RECORD);

    }on String catch(msg){
      SmartDialog.showToast(msg);
    } on ApiException catch(e){
      SmartDialog.showToast(e.message);
    } finally{
      SmartDialog.dismiss();
    }
  }


  void clean() {
    _selectTableInfo = null;
    _shopCarItem.clear();
  }
}

class TableInfo {
  TableModel selectTable;
  int personNum;

  //自定义菜单
  CustomMenuModel? cMenu;

  // // 菜品分类
  // Map<String, CustomMenuListCategoryList>? cacheGroup;
  //
  // // 自定义菜单中的菜品信息
  // Map<String, CategoryListProductList>? cProduct;

  TableInfo(this.selectTable, this.personNum) {
    init();
  }

  void init() {
    var box = store.box<CustomMenuModel>();
    var query = box
        .query(
            CustomMenuModel_.tableList.containsElement(selectTable.tableUuid!))
        .build();
    //匹配的菜单
    var customMenuModel = query.findFirst();
    cMenu = customMenuModel;
    // Map<String, CustomMenuListCategoryList> cacheGroup = {};
    // Map<String, CategoryListProductList> cProduct = {};
    // if (customMenuModel != null) {
    //   for (var e in customMenuModel.categoryList) {
    //     for (var product in e.productList) {
    //       var productId = product.productUuid;
    //       if (productId == null) continue;
    //       cacheGroup[productId] = e;
    //       cProduct[productId] = product;
    //     }
    //   }
    // }
    // this.cacheGroup = cacheGroup;
    // this.cProduct = cProduct;
  }

// void cleanTable(){
//   _selectTable = null;
//   personNum = null;
//
// }
}
class ShopCarItem {
  ShopCarController controller = Get.find<ShopCarController>();
  List<SKU> skus;
  String? notice;
  int count;

  ShopCarItem(this.skus, this.notice, this.count); // ProductModel product;
  //
  // ShopCarItem(this.product);
  //
  String get id {
    return [...skus.map((e) => e.id), notice].join("-");
  }

  @override
  bool operator ==(Object other) {
    if (other is ShopCarItem) {
      return id == other.id;
    }
    return false;
  }

  // 相同的产品默认取第一个
  SKU? get first => skus.firstOrNull;

  SKU? get uiSKU  => inTableSKU?? maxPriceSKU;

  SKU? get maxPriceSKU =>skus.reduce((a,b)=> a.price > b.price ? a : b);

  String get productId => uiSKU?.product.id ?? "";

  String get name => uiSKU?.product.name ?? "";

  String get dish => uiSKU?.dishSpec?.name ?? "";

  String get groupName => uiSKU?.cCategory?.categoryName ?? "";

  String get desc => uiSKU?.desc??"";



  // 判断是否在当前桌台中
  bool isInTable() {
    String? cMenuId = controller.menuId;
    if (cMenuId == null) return true;
    return skus.where((e) => e.id == cMenuId).isNotEmpty;
  }

  SKU? get inTableSKU{
    String? cMenuId = controller.menuId;
    if(cMenuId == null) return null;
    return skus.where((e) => e.cMenuId == cMenuId).firstOrNull;
  }

  // 此产品的价格
  double get price {
    return uiSKU?.price ?? 0;
  }

  @override
  int get hashCode => id.hashCode;

  @override
  String toString() {
    return 'ShopCarItem{controller: $controller, skus: $skus, notice: $notice, count: $count}';
  }
}

///
///
class SKU {
  // 自定义菜单ID,只会在第一次拥有这个参数，skus中的SKU没有此参数
  String? cMenuId;

  // 添加的菜品在自定义菜单中的分类
  CustomMenuListCategoryList? cCategory;

  // 选择的具体菜品
  ProductModel product;

  /// 提供给套餐使用
  int count=1;

  //套餐分组
  List<GroupBox>? group;

  // 自定义菜单中选取的具体规格
  DishList? spec;

  //选取的规格所对应的原始选项
  Spec? dishSpec;

  // 选取的具体选项组 中的选项
  List<SpecOptionBox>? optionList;

  double get price {
    double productPrice = spec?.customPrice ?? dishSpec?.price ?? 0;
    int specPrice = optionList?.fold(0, (pev, e) {
      return (pev??0) + (e.price ?? 0);
    })??0;
    return (specPrice.toD() + productPrice.toD()).toDouble();
  }

  String get id {
    List<String?> ids = [
      cMenuId,
      cCategory?.uuid,
      product.id,
      ...?group?.map((e)=>e.id),
      spec?.uuid,
      ...?optionList?.map((e) => e.idWithCount)
    ];
    return ids.where((e) => e != null).join("/");
  }

  String get desc => optionList?.map((e)=> "${e.spec.name}*${e.count}").join()??"";



  SKU(this.cMenuId, this.cCategory, this.product, this.spec, this.optionList,
      this.dishSpec);

  @override
  String toString() {
    return 'SKU{cMenuId: $cMenuId, cCategory: $cCategory, product: $product, dish: $spec, dishSpec: $dishSpec, specs: $optionList}';
  }


  OrderProductRV toOrderDataRV(){
    var data =  OrderProductRV();
    if(product.isPackage()){
      // 套餐
    var bundleGroup=  group?.map((e){
        var group =  e.group;
        BundleGroupRV v = BundleGroupRV()
        ..type = group.type
        ..max = group.max
        ..name = group.name
        ..id = group.id;

        var productList= e.skus.map((e)=>e.toOrderDataRV()).toList();
        v.productList = productList;
        return v;
      }).toList();
    data.bundleGroup = bundleGroup;

    }else{
      double? productPrice = spec?.customPrice ?? dishSpec?.price ;
      data.specs =[];

    }
    data.categoryId = product .categoryId;
    data.categoryName = product .categoryName;
    data.categoryName = product .categoryName;
    data.id = product .id;
    data.isBundle = product .isBundle;
    data.name = product .name;
    data.price = product.price?.toDouble();
    data.productType = product.isPackage()?1:0;
    data.secondName = product.secondName;
    return data;
  }

}

class GroupBox{
  // 套餐中的菜品列表
  List<SKU> skus;

  //套餐分组
  Group group;

  GroupBox(this.skus, this.group);

  String? get id =>  [
    group.id,
    ...skus.map((e) => e.id)
  ].where((e) => e != null).join("/");


}

class SpecOptionBox {
  int count;
  SpecOption spec;

  SpecOptionBox(this.count, this.spec);

  int? get price => spec.price;

  String? get id => spec.id;

  String? get idWithCount {
    if (id == null) return null;
    return "$id*$count";
  }


}
